﻿module game.battle.collisionmap;

import std.typetuple;
import std.traits;

import game.battle.battlescene;
import game.battle.player;

import game.battle.enemies.suicide;
import game.battle.enemies.fighter;
import game.battle.enemies.missileboat;
import game.battle.enemies.missile;
import game.battle.enemies.backshooter;

import game.battle.projectiles.playerprojectiles;
import game.battle.projectiles.enemyprojectiles;
import game.battle.projectiles.fireprojectiles;

alias CollideableEnemies = TypeTuple!(Suicide,Fighter,MissileBoat,Missile,BackShooter);

bool checkCollision(T)(BattleScene w, ref SimplePlayerProjectile p, T ent)
    if(-1 != staticIndexOf!(Unqual!T,CollideableEnemies))
{
    if(ent.health <= 0) return false;
    auto relPos = p.pos - ent.pos;
    if(relPos.magnitude_squared <= ent.radiusSq)
    {
        ent.health = ent.health - p.damage;
        if(ent.health <= 0)
        {
            w.player.onKilled(ent);
        }
        p.kill();
        SimpleFireProjectile proj;
        proj.pos = p.pos;
        proj.speed = p.speed;
        w.spawnProjectile(proj);
        return true;
    }
    return false;
}

bool checkCollision(BattleScene w, ref SimpleEnemyProjectile p, Player ent)
{
    if(!ent.alive) return false;
    auto relPos = p.pos - ent.pos;
    if(relPos.magnitude_squared <= ent.radiusSq)
    {
        ent.health = ent.health - p.damage;
        p.kill();
        SimpleFireProjectile proj;
        proj.pos = p.pos;
        proj.speed = p.speed;
        w.spawnProjectile(proj);
        return true;
    }
    return false;
}

bool checkCollision(T)(BattleScene w, Player player, T ent)
    if(-1 != staticIndexOf!(Unqual!T,CollideableEnemies))
{
    if(!player.alive || ent.health <= 0) return false;
    auto playerRelPos = player.pos - ent.pos;
    auto rangeSq = (ent.radius + player.radius) ^^ 2;
    if(playerRelPos.magnitude_squared <= rangeSq)
    {
        player.health = player.health - 1;
        ent.health = 0;
        return true;
    }
    return false;
}